//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef _APPS_BUSH_PARSER_CPARSEDWORD_H_
#define _APPS_BUSH_PARSER_CPARSEDWORD_H_

#include <buola/buola.h>
#include <set>

#include "enums.h"
#include "ctoken.h"
#include "cword.h"

namespace buola { namespace bush {

struct CParsedWord
{
    enum EType
    {
        TYPE_EMPTY,
        TYPE_NORMAL,
        TYPE_MULTIPLE,
        TYPE_BRACES
    };
    
    CParsedWord()
        :   mType(TYPE_EMPTY)
    {}
    
    CParsedWord(TTokenRange pRange)
        :   mType(TYPE_NORMAL)
        ,   mRange(pRange)
    {
        
    }
    
    CParsedWord(const CParsedWord &pRH)
        :   mType(pRH.mType)
        ,   mRange(pRH.mRange)
        ,   mChildren(pRH.mChildren)
    {}
    
    CParsedWord(CParsedWord &&pRH)
        :   mType(pRH.mType)
        ,   mRange(pRH.mRange)
        ,   mChildren(std::move(pRH.mChildren))
    {}

    void operator=(const CParsedWord &pRH)
    {
        mType=pRH.mType;
        mRange=pRH.mRange;
        mChildren=pRH.mChildren;
    }
    
    void operator=(CParsedWord &&pRH)
    {
        mType=pRH.mType;
        mRange=pRH.mRange;
        mChildren=std::move(pRH.mChildren);
    }

    EType GetType() {   return mType;               }
    bool empty()  {   return mType==TYPE_EMPTY;   }
    TTokenRange GetTokenRange()   {   return mRange;  }

    void AddNormal(const CParsedWord &pW)
    {
        if(mType==TYPE_EMPTY)
        {
            *this=pW;
            return;
        }
        else if(mType!=TYPE_MULTIPLE)
        {
            std::vector<CParsedWord> lChildren;
            lChildren.push_back(std::move(*this));
            mType=TYPE_MULTIPLE;
            mChildren=std::move(lChildren);
        }
        mChildren.push_back(pW);
    }
    
    void AddBraces(const CParsedWord &pW)
    {
        mType=TYPE_BRACES;
        mChildren.push_back(pW);
    }

    void Print(int pDepth=0)
    {
        for(int i=0;i<pDepth;i++)
            msg_info() << "  ";
        msg_info() << (int)mType << "\n";
        for(int i=0;i<mChildren.size();i++)
            mChildren[i].Print(pDepth+1);      
    }

    void ExpandSimple(CWord &pResult);
    void ExpandMultiple(std::vector<CWord> &pResult,bool pComplete=true);

private:    
    EType mType;
    TTokenRange mRange;
    std::vector<CParsedWord> mChildren;
};

/*namespace bush*/ } /*namespace buola*/ }

#endif
